package com.papper.common.service.sys;

import com.google.common.base.Splitter;
import com.papper.common.bean.sys.SysLimit;
import com.papper.common.bean.sys.SysUser;
import com.papper.common.cache.CacheConstants;
import com.papper.common.cache.local.GuavaCacheFactory;
import com.papper.common.enums.LimitTypeEnum;
import com.papper.common.mapper.sys.SysLimitMapper;
import com.papper.common.service.ServiceImpl;
import com.papper.common.utils.tool.DateTool;
import com.papper.common.utils.tool.StringTool;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

@Service("sysLimitService")
public class SysLimitService extends ServiceImpl<SysLimitMapper, SysLimit> {

	/**
	 * function
	 */
	public List<SysLimit> getUserLimits(SysUser sysUser) {
		if (sysUser.getLimitType().intValue() == LimitTypeEnum.GROUP.getCode()) {
			return getGroupLimits(sysUser.getGroupId().longValue());
		} else if (sysUser.getLimitType().intValue() == LimitTypeEnum.USER.getCode()) {
			return getUserLimits(sysUser.getId().longValue(), null, false);
		}
		return null;
	}

	public List<SysLimit> getUserLimits(int type, Long id) {
		if (type == 0) {
			return getGroupLimits(id);
		}
		if (type == 1) {
			return getUserLimits(id, null, false);
		}

		return null;
	}

	public List<SysLimit> getGroupLimits(Long gid) {
		Example          example  = new Example(SysLimit.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("limitType", 0);
		criteria.andEqualTo("limitId", gid);
		return find(example);
	}

	public int limit(Integer limitType, Long limitId, String limitKey) {
		Object v = GuavaCacheFactory.instance().get("SysLimit", CacheConstants.Keys(limitType, limitId, limitKey));
		if (v == null) {
			int rtn = getPapperMapper().limit(limitType, limitId, limitKey);
			GuavaCacheFactory.instance().put("SysLimit", CacheConstants.Keys(limitType, limitId, limitKey), rtn + "_" + DateTool.formatDate(new Date(), DateTool.FULL_TRADITION_PATTERN));
			return rtn;
		}
		List<String> lst = Splitter.on("_").omitEmptyStrings().splitToList(v.toString());
		if (DateTool.getNumberOfMinuteBetween(DateTool.parseDate(lst.get(1), DateTool.FULL_TRADITION_PATTERN), new Date()) > 2) {
			int rtn = getPapperMapper().limit(limitType, limitId, limitKey);
			GuavaCacheFactory.instance().put("SysLimit", CacheConstants.Keys(limitType, limitId, limitKey), rtn + "_" + DateTool.formatDate(new Date(), DateTool.FULL_TRADITION_PATTERN));
			return rtn;
		}
		return StringTool.parseInteger(lst.get(0), null);
	}

	public SysLimit getUserLimit(Integer limitType, Long uid, Integer gid, Long resId) {
		Example          example  = new Example(SysLimit.class);
		Example.Criteria criteria = example.createCriteria().andEqualTo("limitType", limitType);
		if (LimitTypeEnum.GROUP.getCode().equals(limitType)) {
			criteria.andEqualTo("limitId", gid);
		} else {
			criteria.andEqualTo("limitId", uid);
		}
		criteria.andEqualTo("resId", resId);
		example.setOrderByClause("id desc limit 1");
		SysLimit rtn = findOne(example);
		return rtn;
	}

	public List<SysLimit> getUserLimits(Long uid, Long gid, boolean bUserGroupLimits) {
		Example example = new Example(SysLimit.class);
		example.createCriteria().andEqualTo("limitType", 1).andEqualTo("limitId", uid);
		List<SysLimit> list = find(example);
		if (list != null && !list.isEmpty()) {
			return list;
		}
		if (bUserGroupLimits) {
			example.clear();
			example.createCriteria().andEqualTo("limitType", 0).andEqualTo("limitId", gid);
			return find(example);
		}
		return list;
	}

	public void delLimitedByGroupIds(String ids) {
		if (StringTool.isEmpty(ids)) {
			return;
		}
		Example          example  = new Example(SysLimit.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("limitType", LimitTypeEnum.GROUP.getCode());
		criteria.andIn("limitId", StringTool.stringToListString(ids, ","));
		delete(example);
	}

	public void delLimitedByUserIds(String ids) {
		if (StringTool.isEmpty(ids)) {
			return;
		}
		Example          example  = new Example(SysLimit.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("limitType", LimitTypeEnum.USER.getCode());
		criteria.andIn("limitId", StringTool.stringToListString(ids, ","));
		delete(example);
	}

	public void delLimitedByResId(Long id) {
		Example example = new Example(SysLimit.class);
		example.createCriteria().andEqualTo("resId", id);
		delete(example);
	}
}